package sat.component;

import java.util.LinkedList;
import java.util.List;

import org.mt4j.MTApplication;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.visibleComponents.shapes.MTRectangle;
import org.mt4j.components.visibleComponents.shapes.MTRoundRectangle;
import org.mt4j.components.visibleComponents.widgets.MTList;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapProcessor;
import org.mt4j.util.MTColor;
import org.mt4j.util.math.Vector3D;

import sat.component.ClassComponent.entityType;
import sat.component.DragAndDropButton.ButtonType;
import sat.model.ClassModel;

public class ClassComponentPopUp extends UMLPopUp{

	private MTRectangle nameField;

	private MTList attributeList;

	private boolean nameTextModified = false;

	private List<Keyboard> keyBoardList = new LinkedList<Keyboard>();

	private  Vector3D pos = null;

	private MTList operationList;

	private KeyboardTextField nameText;

	private ClassModel model;

	private entityType eType; // entity type {class, interface}

	private ClassComponentPopUp instance;

	private MTApplication app;

	public static final float nameFieldHeight = 30;

	public static final float listWidthPreferred = (heightPreferred-nameFieldHeight)/2;

	public entityType geteType() {
		return eType;
	}

	public MTList getAttributeList() {
		return attributeList;
	}

	public MTList getOperationList() {
		return operationList;
	}

	public List<String> MTListToStringList(MTList l){
		List<String> res = new LinkedList<String>();
		for (int i = 0; i < l.getChildByIndex(0).getChildCount()-1; i++) {
			res.add(i,((ClassPopupItem)l.getChildByIndex(0).getChildByIndex(i)).toString());
		}
		return res;
	}

	public void addKeyboard(Keyboard kb){
		this.keyBoardList.add(kb);
	}

	public void closeAllKeyboard(){
		for (int i = 0; i < keyBoardList.size(); i++) {
			keyBoardList.get(i).close();
			keyBoardList.get(i).getTextField().setFlagKeyboard(true); //enable to add a keyboard for the next time
			keyBoardList.get(i).getTextField().setEnableCaret(false);
		}
	}

	public void clearAll(){
		nameText.setText("");
		attributeList.removeAllListElements();
		attributeList.addListElement(new ClassPopupItem(this.app,attributeList,this));
		operationList.removeAllListElements();
		operationList.addListElement(new ClassPopupItem(this.app,operationList,this));

		// refresh the view
		attributeList.setHeightLocal(ClassComponentPopUp.listWidthPreferred);
		operationList.setHeightLocal(ClassComponentPopUp.listWidthPreferred);
		operationList.setPositionRelativeToParent(
				new Vector3D(ClassComponentPopUp.widthPreferred/2,
						ClassComponentPopUp.nameFieldHeight/2
						+ ( eType == entityType.CLASS ? attributeList.getHeightXY(TransformSpace.RELATIVE_TO_PARENT) : 0)
						+operationList.getHeightXY(TransformSpace.RELATIVE_TO_PARENT)/2+15)
				);
		this.setHeightLocal(eType == entityType.CLASS ? heightPreferred : listWidthPreferred+nameFieldHeight);
		this.refreshBottomButtonPositionY();

		this.translate(new Vector3D(0,this.model.getView().getPosition(TransformSpace.GLOBAL).y - this.getPosition(TransformSpace.GLOBAL).y));
	}

	public void highLightValid(){
		//this.setStrokeColor(new MTColor(202,94,47));
		this.setStrokeColor(MTColor.GREEN);
		instance.setStrokeWeight(10);
	}

	public void highLightInvalid(){
		//this.setStrokeColor(new MTColor(202,94,47));
		this.setStrokeColor(MTColor.RED);
		instance.setStrokeWeight(10);
	}

	public void lowLight(){
		instance.setStrokeColor(new MTColor(56, 62, 52, 255));
		this.setStrokeWeight(1);
	}

	public void refreshClass(){
		String text = nameTextModified ? nameText.getText() : "";
		if(instance.eType == entityType.CLASS)
			model.refreshModel(text ,MTListToStringList(attributeList),MTListToStringList(operationList));
		else
			model.refreshModel(text ,MTListToStringList(operationList));
	}

	public void addCornerButtonListener(final MTRoundRectangle button,final ButtonType t){

		button.addGestureListener(DragProcessor.class,new IGestureEventListener() {
			public boolean processGestureEvent(MTGestureEvent evt) {
				DragEvent de = (DragEvent) evt;

				switch (de.getId()) {
				case MTGestureEvent.GESTURE_STARTED:
					System.out.println("start");

					pos = new Vector3D(button.getCenterPointRelativeToParent());
					// freeze other buttons which is not selected
					if(t == ButtonType.SAVE){
						clearButton.setPickable(false);
						saveAndQuitButton.setPickable(false);
						quitButton.setPickable(false);
					}
					else if(t == ButtonType.CLEAR){
						saveButton.setPickable(false);
						saveAndQuitButton.setPickable(false);
						quitButton.setPickable(false);
					}
					else if(t == ButtonType.SAVEANDQUIT){
						saveButton.setPickable(false);
						clearButton.setPickable(false);
						quitButton.setPickable(false);
					}
					else if(t == ButtonType.QUIT){
						saveButton.setPickable(false);
						clearButton.setPickable(false);
						saveAndQuitButton.setPickable(false);
					}
					highLightInvalid();
					break;
				case MTGestureEvent.GESTURE_UPDATED:
					System.out.println("update");
					if(instance.isGeometryContainsPointLocal(button.getCenterPointRelativeToParent())){
						highLightValid();
					}
					else{
						highLightInvalid();
					}
					break;
				case MTGestureEvent.GESTURE_ENDED:

					//set free other buttons which is not selected
					if(t == ButtonType.SAVE){
						clearButton.setPickable(true);
						saveAndQuitButton.setPickable(true);
						quitButton.setPickable(true);
					}
					else if(t == ButtonType.CLEAR){
						saveButton.setPickable(true);
						saveAndQuitButton.setPickable(true);
						quitButton.setPickable(true);
					}
					else if(t == ButtonType.SAVEANDQUIT){
						saveButton.setPickable(true);
						clearButton.setPickable(true);
						quitButton.setPickable(true);
					}
					else if(t == ButtonType.QUIT){
						saveButton.setPickable(true);
						clearButton.setPickable(true);
						saveAndQuitButton.setPickable(true);
					}

					if(instance.isGeometryContainsPointLocal(button.getCenterPointRelativeToParent()))
					{
						//TODO		
						
						if(t == ButtonType.SAVE){
							System.out.println("Saving...");
							refreshClass();
							instance.translate(new Vector3D(0,model.getView().getPosition(TransformSpace.GLOBAL).y - getPosition(TransformSpace.GLOBAL).y));
						}
						else if(t == ButtonType.CLEAR){
							System.out.println("Clear");
							clearAll();
							closeAllKeyboard();
						}
						else if(t == ButtonType.SAVEANDQUIT){
							System.out.println("Saved and quit");
							closeAllKeyboard();
							refreshClass();
							instance.translate(new Vector3D(0,model.getView().getPosition(TransformSpace.GLOBAL).y - getPosition(TransformSpace.GLOBAL).y));
							instance.setVisible(false);
						}
						else if(t == ButtonType.QUIT){
							instance.setVisible(false);
							closeAllKeyboard();
							System.out.println("Quit");
						}
					}
					button.setPositionRelativeToParent(pos);
					lowLight();
				default:
					break;
				}
				return false;
			}
		});	
	}

	public ClassComponentPopUp(MTApplication mtApplication, ClassModel model, entityType enttype) {
		super(mtApplication,enttype);

		// TODO Auto-generated constructor stub
		nameField = new MTRectangle(mtApplication,widthPreferred,nameFieldHeight);
		attributeList = new MTList(mtApplication, 0, 0, widthPreferred, listWidthPreferred,2);
		operationList = new MTList(mtApplication, 0, 0, widthPreferred,listWidthPreferred);

		instance = this;
		this.model = model;
		app = mtApplication;
		eType = enttype;

		this.setFillColor(new MTColor(122, 142, 117, 255));
		this.setStrokeColor(new MTColor(56, 62, 52, 255));
		this.setStrokeWeight(1);

		nameText = new KeyboardTextField (mtApplication,widthPreferred,nameFieldHeight,KeyboardTextField.type.classes, this,null);
		nameText.setFillColor(new MTColor(122, 142, 117, 255));
		nameText.setStrokeColor(new MTColor(164, 117, 91, 255));
		nameText.setText("Tap here to set class name");
		nameText.removeAllGestureEventListeners(DragProcessor.class);
		nameText.removeAllGestureEventListeners(RotateProcessor.class);
		nameText.removeAllGestureEventListeners(ScaleProcessor.class);
		nameText.addGestureListener(TapProcessor.class, new IGestureEventListener() {
			@Override
			public boolean processGestureEvent(MTGestureEvent ge) {
				// TODO Auto-generated method stub
				TapEvent te = (TapEvent)ge;
				switch (te.getTapID()) {
				case TapEvent.TAPPED:
					if(! nameTextModified){
						nameText.setText("");
						nameTextModified = true;
					}
					break;
				default:
					break;

				}
				return false;
			}

		});

		nameField.addChild(nameText);
		nameField.setFillColor(new MTColor(122, 142, 117, 255));
		nameField.setStrokeColor(new MTColor(164, 117, 91, 255));
		nameField.setStrokeWeight(3);

		if(enttype == entityType.CLASS){
			attributeList.setFillColor(new MTColor(122, 142, 117, 255));
			attributeList.setStrokeColor(new MTColor(164, 117, 91, 255));
			attributeList.setStrokeWeight(3);
			attributeList.addListElement(new ClassPopupItem(mtApplication,attributeList,this));
		}
		else
			this.setHeightLocal(listWidthPreferred+nameFieldHeight);

		operationList.setFillColor(new MTColor(122, 142, 117, 255));
		operationList.setStrokeColor(new MTColor(164, 117, 91, 255));
		operationList.setStrokeWeight(3);

		operationList.addListElement(new ClassPopupItem(mtApplication,operationList,this));

		this.addChild(nameField);
		if(enttype == entityType.CLASS){
			this.addChild(attributeList);
			attributeList.setPositionRelativeToParent(new Vector3D(widthPreferred/2,nameFieldHeight+(heightPreferred-nameFieldHeight)/4));
			this.addChild(operationList);
			operationList.setPositionRelativeToParent(new Vector3D(widthPreferred/2,nameFieldHeight+(heightPreferred-nameFieldHeight)/4*3));
		}
		else{
			this.addChild(operationList);
			operationList.setPositionRelativeToParent(new Vector3D(widthPreferred/2,nameFieldHeight+(heightPreferred-nameFieldHeight)/4));
		}

		nameField.setPickable(false);
		attributeList.setPickable(false);
		operationList.setPickable(false);

		this.removeAllGestureEventListeners(ScaleProcessor.class);

		this.addCornerButtonListener(saveButton, ButtonType.SAVE);
		this.addCornerButtonListener(clearButton, ButtonType.CLEAR);
		this.addCornerButtonListener(saveAndQuitButton, ButtonType.SAVEANDQUIT);
		this.addCornerButtonListener(quitButton, ButtonType.QUIT);
	}
}
